home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 108_01 / merge.c < prev    next >
Text File  |  1985-11-13  |  4KB  |  153 lines

  1.  
  2. /**********************************************************
  3.  ***                            ***
  4.  ***    Copyright (c) 1981 by David M. Fogg        ***
  5.  ***                            ***
  6.  ***        2632 N.E. Fremont            ***
  7.  ***        Portland, OR 97212            ***
  8.  ***                            ***
  9.  ***        (503) 288-3502{HM} || 223-8033{WK}        ***
  10.  ***                            ***
  11.  ***    Permission is herewith granted for non-     ***
  12.  ***    commercial distribution through the BDS C    ***
  13.  ***    User's Group; any and all forms of commercial   ***
  14.  ***    redistribution are strenuously unwished-for.    ***
  15.  ***                            ***
  16.  **********************************************************/
  17.  
  18. /* --->  MERGE.C  <--- : merge utility for use w/ msort
  19.  
  20.     30 Oct 80: convert WC->BDS; add ignore case code
  21.     4 Feb 81: chg MORDER; MAXLEN --> MAXLINE
  22.  
  23.     SYNOPSIS: sort mfiles to ofile
  24.     NB: merge file names have format mfile.X+
  25.         (where X = A, B, C, ... )
  26. */
  27.  
  28. #include <std.h>
  29.  
  30. #define MORDER    7    /* merge order: max merge files/pass */
  31.  
  32. main(ac, av)
  33. int ac;
  34. char *av[];
  35. {
  36.    char lbuf[MAXLINE * MORDER];  /* merge line buffer */
  37.    char *lb;            /* tempointer into lbuf */
  38.    int len;
  39.    char *linptr[MORDER];    /* pointers into lbuf */
  40.    char inam[15];        /* input file name(s) */
  41.    int nfils;               /* # of merge files */
  42.    int nf, fno;
  43.    BOOL nokill;         /* have mercy on infiles flag */
  44.    BOOL back;            /* backward order flag */
  45.    BOOL igcas;              /* ignore case flag */
  46.    int tlins;              /* tot lines writ out */
  47.    int cloc;              /* chg loc in inam */
  48.    char ibuf[MORDER][BUFSIZ]; /* input buffers */
  49.    char obuf[BUFSIZ];          /* output buffer */
  50.    int argn;              /* curr comm ln arg # */
  51.    char *arg;              /* curr comm ln arg ptr */
  52.  
  53.    nfils = tlins = 0;
  54.    igcas = nokill = back = NO;
  55.  
  56.    if (ac < 3) {
  57.       puts("usage: merge MFILE OFILE [-I -K -R]\n");
  58.       puts("MFILE: input from MFILE.A+, MFILE.B+, etc.\n");
  59.       puts("OFILE: output file name\n");
  60.       puts("   -I: ignore case (treat uppercase as lowercase)\n");
  61.       puts("   -K: don't Kill merge files\n");
  62.       puts("   -R: Reverse order merge\n");
  63.       exit ();
  64.    }
  65.  
  66. /*
  67.    ---> GET OPTIONS <---
  68. */
  69.    for (argn = 3; argn < ac; ++argn) {
  70.       arg = av[argn];
  71.       if (*arg == '-')
  72.      switch (arg[1]) {
  73.         case 'I':
  74.            igcas = YES;
  75.            break;
  76.         case 'K':
  77.            nokill = YES;
  78.            break;
  79.         case 'R':
  80.            back = YES;
  81.            break;
  82.         default :
  83.            errxit("Bad option value");
  84.      }
  85.    }
  86.  
  87.    strcpy(inam, av[1]); strcat(inam,".A+");
  88.    cloc = instr(inam,".A+");
  89.  
  90.    if (fcreat(av[2], obuf) == ERROR)
  91.       errxit("Output file error");
  92.  
  93.    while (nfils < MORDER) {         /* open files & read 1st lns */
  94.       if (fopen(inam, ibuf[nfils]) == ERROR)
  95.      break;
  96.       lb = lbuf + nfils * MAXLINE;
  97.       if (fgets(lb, ibuf[nfils]) != 0) {
  98.      len = strlen(lb);
  99.      *(lb + --len) = NULL;    /* replace \n w/ string terminator */
  100.      linptr[nfils++] = lb;
  101.       }
  102.       else
  103.      fclose(ibuf[nfils]);  /* close mt file */
  104.       ++inam[cloc];          /* bump filename */
  105.    }
  106.  
  107.    strcpy(inam, av[1]); strcat(inam,".A+");   /* rewind filenames */
  108.  
  109.    if (nfils == 0)
  110.       errxit("no input files");
  111.  
  112.    if (nfils == 1) {
  113.       fputs(lbuf, obuf);
  114.       fputs("\n", obuf);
  115.       while (fgets(lbuf, ibuf[0]) != 0)
  116.      fputs(lbuf, obuf);     /* trivial case: copy only merge fl->STDOUT */
  117.       oclose(obuf);
  118.       fclose(ibuf[0]);
  119.       if (!nokill)
  120.      unlink(inam);
  121.       errxit("1 file merged");
  122.    }
  123.  
  124.    quick(linptr, 0, nfils - 1, back, igcas);   /* form initial heap */
  125.  
  126. /*
  127.     ---> MAIN LOOP <---
  128. */
  129.    nf = nfils;
  130.  
  131.    while (nf) {
  132.       lb = linptr[0];
  133.       fprintf(obuf, "%s\n", lb);
  134.       ++tlins;
  135.       fno = (lb - lbuf) / MAXLINE;    /* calc file # */
  136.       if (fgets(lb, ibuf[fno]) != 0) {
  137.      len = strlen(lb);
  138.      *(lb + --len) = NULL;
  139.       }
  140.       else {
  141.      fclose(ibuf[fno]);
  142.      if (!nokill) {
  143.         inam[cloc] = 'A' + fno;
  144.         unlink(inam);
  145.      }
  146.      linptr[0] = linptr[--nf];
  147.       }
  148.       reheap(linptr, nf, back, igcas);           /* put 1st ln in its place */
  149.    }
  150.    printf("%d files merged     %d lines writ\n", nfils, tlins);
  151.    oclose(obuf);
  152. }
  153.